package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.constants.RedisConstants;
import com.tianji.learning.domain.po.PointsRecord;
import com.tianji.learning.domain.vo.PointsStatisticsVO;
import com.tianji.learning.enums.PointsRecordType;
import com.tianji.learning.mapper.PointsRecordMapper;
import com.tianji.learning.service.IPointsRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 学习积分记录，每个月底清零 服务实现类
 * </p>
 *
 * @author xzh
 * @since 2024-03-18
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class PointsRecordServiceImpl extends ServiceImpl<PointsRecordMapper, PointsRecord> implements IPointsRecordService {

    private final StringRedisTemplate redisTemplate;

    private final PointsRecordMapper pointsRecordMapper;

    /**
     * 新增积分记录
     *
     * @param record
     */
    @Override
    public void savePointsRecord(PointsRecord record) {
        save(record);
    }

    /**
     * 每天24点清理redis中的pointsRecord记录 赋值为0
     */
    @Override
    public void updateRedisPointsRecord() {


        //清理redis中数据记录  直接将数据库给删除
        // unlike 方法  不会占用主线程  redis会分出一个副线程用来执行这个方法

        redisTemplate.unlink(RedisConstants.LEARN_POINTS_KEY);
        redisTemplate.unlink(RedisConstants.WRITE_POINTS_KEY);
    }

    /**
     * 查询每天不同类型的积分情况
     *
     * @return
     */
    @Override
    public List<PointsStatisticsVO> queryMyPointsToday() {
        // 1.获得当前登录用户的id
        Long userId = UserContext.getUser();
        LocalDateTime endTime = DateUtils.getDayEndTime(LocalDateTime.now());
        LocalDateTime startTime = DateUtils.getDayStartTime(LocalDateTime.now());

        QueryWrapper<PointsRecord> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(PointsRecord::getUserId, userId)
                .between(PointsRecord::getCreateTime, startTime, endTime);
        // 查询 todo
        List<PointsRecord> list = pointsRecordMapper.queryUserPointsByDate(wrapper);
        if (CollUtils.isEmpty(list)) {
            return CollUtils.emptyList();
        }
        List<PointsStatisticsVO> listvo = new ArrayList<>(list.size());
        PointsStatisticsVO vo = new PointsStatisticsVO();
        for (PointsRecord record : list) {
            if (record.getType() == PointsRecordType.LEARNING.getValue()) {
                // 学习完成小节
                vo.setType(PointsRecordType.LEARNING.getDesc());
                vo.setMaxPoints(PointsRecordType.LEARNING.getMaxPoints());
                vo.setPoints(record.getPoints());
                listvo.add(vo);
            } else if (record.getType() == PointsRecordType.QA.getValue()) {
                //回答问题
                vo.setType(PointsRecordType.QA.getDesc());
                vo.setMaxPoints(PointsRecordType.QA.getMaxPoints());
                vo.setPoints(record.getPoints());
                listvo.add(vo);
            } else if (record.getType() == PointsRecordType.NOTE.getValue()) {
                //做笔记
                vo.setType(PointsRecordType.NOTE.getDesc());
                vo.setMaxPoints(PointsRecordType.NOTE.getMaxPoints());
                vo.setPoints(record.getPoints());
                listvo.add(vo);
            } else if (record.getType() == PointsRecordType.COMMENT.getValue()) {
                //评价
                vo.setType(PointsRecordType.COMMENT.getDesc());
                vo.setMaxPoints(PointsRecordType.COMMENT.getMaxPoints());
                vo.setPoints(record.getPoints());
                listvo.add(vo);
            } else if (record.getType() == PointsRecordType.SIGN.getValue()) {
                //每日登录
                vo.setType(PointsRecordType.SIGN.getDesc());
                vo.setMaxPoints(PointsRecordType.SIGN.getMaxPoints());
                vo.setPoints(record.getPoints());
                listvo.add(vo);
            }
        }
        return listvo;
    }

    /**
     * 学习积分记录，每个月底清零 服务类
     *
     * @param beginTime
     * @param endTime
     */
    @Override
    public void clearPointsRecordFromDB(LocalDateTime beginTime, LocalDateTime endTime) {
        // 查出上个月的学习记录集合
        List<PointsRecord> list = lambdaQuery()
                .between(PointsRecord::getCreateTime, beginTime, endTime).list();
        //健壮性判断
        if (CollUtils.isNotEmpty(list)){
            //获得id集合
            List<Long> ids = list.stream().map(PointsRecord::getId).collect(Collectors.toList());

            //批量删除
            removeByIds(ids);
        }

    }
}
